package rpg.avatar
{
	import flash.utils.Dictionary;

	import rpg.Utils.GameUtils;
	import rpg.Utils.Log;
	import rpg.Utils.StringUtil;
	import rpg.animation.Animation;
	import rpg.animation.AvatarActionDescription;
	import rpg.animation.AvatarDescription;
	import rpg.animation.Frame;
	import rpg.interfaces.IDestroy;
	import rpg.manager.AnimationManager;
	import rpg.render.RenderData;

	public class Avatar implements IDestroy
	{
		private var avatarDes : AvatarDescription;

		/**
		 * 当前动作名称
		 */
		private var curAction : String;
		/**
		 * 方向
		 */
		public var dir : int;

		/**
		 * 人物的所有动作数据
		 */
		public var actionsDirAnimation : Dictionary

		public var render : RenderData = new RenderData();

		/**
		 * 当前播放的动画
		 */
		public var curAnimation : Animation;

		public var width : int;
		public var height : int;

		public function Avatar(avatarDes : AvatarDescription)
		{
			this.avatarDes = avatarDes;
			this.render.name = avatarDes.name;
		}

		/**
		 * 更换动作,方向
		 * @param action 动作名称
		 * @param dir    方向
		 * @param index  帧数
		 * @param loops  循环次数
		 *
		 */
		public function goto(action : String , dir : int , index : int = 0 , loops : int = 0) : Frame
		{
			if(actionsDirAnimation == null)
			{
				Log.error("没有可用序列帧");
				return null;
			}
			if(!hasAction(action))
			{
				Log.error("没有可用该动作序列帧:" , action);
				return null;
			}
			this.curAction = action;
			if(!hasDir(dir))
			{
				Log.error("没有可用该方向序列帧:" , dir);
				return null;
			}
			this.dir = dir;
			var actionDesc : AvatarActionDescription = avatarDes.getActionDescriptionByName(action);
			if(actionDesc)
			{
				if(actionDesc.hasCenterInfo)
				{
					width = actionDesc.width;
					height = actionDesc.height;
				}
				else
				{
					width = avatarDes.width;
					height = avatarDes.height;
				}
			}
			curAnimation = actionsDirAnimation[action][dir];
			curAnimation.loops = loops;
			return curAnimation.gotoFrame(index);
		}

		/**
		 * 换方向
		 * @param dir [0-7]
		 * @return
		 */
		public function gotoDirection(dir : int) : Frame
		{
			return goto(curAction , dir , curAnimation ? curAnimation.curFrameIndex : 0);
		}

		private function hasAction(action : String) : Boolean
		{
			return actionsDirAnimation[action] != null;
		}

		private function hasDir(dir : int) : Boolean
		{
			return actionsDirAnimation[curAction][dir] != null;
		}

		/**
		 * 尝试是否可以播放下一帧
		 * @param elapsedTime
		 * @param duration
		 * @return
		 *
		 */
		public function tryNext(elapsedTime : int , duration : int = 0) : Frame
		{
			var frame : Frame = curAnimation ? curAnimation.tryNext(elapsedTime , duration) : null;
			return frame;
		}

		public function updateRender(sceneX : int , sceneY : int , offsetX : int = 0 , offsetY : int = 0) : void
		{
			if(curAnimation == null)
			{
				Log.warning("当前帧是空帧:" + avatarDes.name);
				return;
			}
			var frame : Frame = curAnimation.curFrame;
			if(frame.data == null && frame.frameClass)
			{
				frame.data = new frame.frameClass(0 , 0);
			}
			render.bitmapData = frame.data;
			render.x = sceneX + frame.offsetX - offsetX;
			render.y = sceneY + frame.offsetY - offsetY;
		}

		/**
		 * 检测鼠标是否在人物上面.
		 * 根据宽高检测,属于模糊查询
		 * @param mouseX
		 * @param mouseY
		 * @return
		 *
		 */
		public function checkIsMouseIn(mouseX : int , mouseY : int) : Boolean
		{
			if(mouseX < render.x || mouseX > render.x + render.width)
				return false;
			if(mouseY < render.y || mouseY > render.y + render.height)
				return false;
			return true;
		}

		public function checkIsReaLMouseIn(mouseX : int , mouseY : int) : Boolean
		{
			if(!checkIsMouseIn(mouseX , mouseY))
				return false;
			if(!render.bitmapData)
				return false;
			return render.bitmapData.getPixel(mouseX - render.x , mouseY - render.y) != 0;
		}

		public function get isEnd() : Boolean
		{
			return curAnimation.isEnd;
		}

		public function destroy() : void
		{
			render.destory();
			avatarDes = null;
			actionsDirAnimation = null;
			curAnimation.destroy();
			curAnimation = null;
		}

	}
}